<?php

	/* dependence */
	CoreProject::Using('db.sql');
	
	/**
	 * @final
	 * @package		CoreProject
	 * @subpackage	Db
	 *
	 * @example
	 *		../examples/mysql.php
	 * 
	 * cpr_Db_MySql
	 * 
	 */

	final class cpr_Db_MySql extends cpr_Db_aSql
	{
		/**
		 * @return	bool
		 */
		public function Connect()
		{
			if (!extension_loaded('mysql'))
			{
				$this->_initError('extension MySQL not loaded');
				return false;
			}
			$this->_connect = @mysql_connect($this->_sqlConfig->Host(), $this->_sqlConfig->Login(), $this->_sqlConfig->Password());
			if ($this->_connect)
			{
				if (strlen($this->_sqlConfig->DataBaseName()) > 0)
				{
					$_dbSelect = @mysql_select_db($this->_sqlConfig->DataBaseName(), $this->_connect);
					if (!$_dbSelect)
					{
						$this->_initError();
						@mysql_close($this->_connect);
						$this->_conection = null;
						return false;
					}
				}
				return true;
			}
			else
			{
				$this->_initError();
				return false;
			}
		}
		
		/**
		 * @return	true
		 */
		public function Disconnect()
		{
			if ($this->_connect)
			{
				if ($this->_result)
				{
					@mysql_free_result($this->_result);
				}
				@mysql_close($this->_connect);
			}
			$this->_result = null;
			$this->_connect = null;
			return true;
		}

		function  __destruct()
		{
			$this->Disconnect();
		}
		
		/**
		 * @param	string	$sql
		 * @return	resource|false
		 */
		public function Query($_sql)
		{
			if (!$this->_connect)
			{
				if (!$this->Connect())
				{
					return false;
				}
			}
			
			cpr_Core_Log::Write('MYSQL: > '.$_sql);
			$this->_result = @mysql_query($_sql, $this->_connect);
			if (false === $this->_result)
			{
				$this->_initError();
			}
			
			return $this->_result;
		}

		/**
		 * @return	object
		 */
		public function GetNextObject()
		{
			return ($this->_result)
				? @mysql_fetch_object($this->_result)
				: null;
		}

		/**
		 * @return	array
		 */
		public function GetNextArray()
		{
			return ($this->_result)
				? @mysql_fetch_assoc($this->_result)
				: null;
		}

		/**
		 * @return	array
		 */
		public function GetRecords($_type = cpr_Db_aSql::CPR_FETCH_TYPE_OBJECT)
		{
			$_return = array();

			if ($this->_result)
			{
				$_row = null;
				$_functionName = 'GetNextObject';
				switch ($_type)
				{
					case cpr_Db_aSql::CPR_FETCH_TYPE_ARRAY:
						$_functionName = 'GetNextArray';
						break;
				}

				while (null != ($_row = call_user_method($_functionName, $this)))
				{
					$_return[] = $_row;
				}
			}
			return $_return;
		}

		/**
		 * @return	int
		 */
		public function GetLastInsertId()
		{
			return @mysql_insert_id($this->_connect);
		}

		/**
		 * @return	int
		 */
		public function GetAffectedRows()
		{
			return @mysql_affected_rows($this->_connect);
		}
		
		/**
		 * @return	int
		 */
		public function ResultCount()
		{
			return @mysql_num_rows($this->_result);
		}
		
		/**
		 * @return	true
		 */
		public function FreeResult()
		{
			if ($this->_result)
			{
				@mysql_free_result($this->_result);
			}
			
			$this->_result = null;
			return true;
		}

		/**
		 * @return	bool
		 */
		public function TBegin()
		{
			return $this->Query('BEGIN');
		}

		/**
		 * @return	bool
		 */
		public function TCommit()
		{
			return $this->Query('COMMIT');
		}

		/**
		 * @return	bool
		 */
		public function TRollBack()
		{
			return $this->Query('ROLLBACK');
		}

		/**
		 * @param	string	$_str
		 * @return	string
		 */
		public function QuoteName($_str)
		{
			return '`'.$_str.'`';
		}

		/**
		 * @param	string	$_str
		 * @return	string
		 */
		public function QuoteString($_str)
		{
			if ($_str === '' || $_str === null)
			{
				return "''";
			}
			
			return "'".addslashes($_str)."'";
		}

		/**
		 * @param	string	$fieldName
		 * @return	string
		 */
		public function DateFormatString($fieldName)
		{
			return 'DATE_FORMAT('.$fieldName.', "%Y-%m-%d %T") as '.$fieldName;
		}
		
		/**
		 * @param	string	$errorDesc = null
		 */
		private function _initError($_errorDesc = null)
		{
			if ($this->_connect)
			{
				$this->SetError(@mysql_error($this->_connect), @mysql_errno($this->_connect));
			}
			else
			{
				$this->SetError(@mysql_error(), @mysql_errno());
			}
			
			if (null !== $_errorDesc && 0 === strlen($this->GetErrorString()))
			{
				$this->SetError($_errorDesc);
			}
		}
	}
